package org.cl.persist.system.controller;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.cl.persist.system.data.dto.Dict;
import org.cl.persist.system.data.fo.DictFo;
import org.cl.persist.system.data.vo.SimpleDictVo;
import org.cl.persist.system.service.QueryWrapperPlus;
import org.cl.persist.system.service.impl.DictServiceImpl;
import org.springboot.gls.ex.request.ret.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author cl
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/dict")
public class DictController {

    @Autowired
    private DictServiceImpl dictService;

    /**
     * 条件查询
     * 分页查询一级字典信息
     * @return 分页对象
     */
    @GetMapping("/getPage1")
    public R<IPage<SimpleDictVo>> getPage(@Valid DictFo dictFo) {
        // 0 表示一级字典
        dictFo.setPId(0);
        // 不指定默认是未删除的
        if (dictFo.getDelFlag() == null) {
            dictFo.setDelFlag(false);
        }
        IPage<Dict> data = dictService.page(new Page<>(dictFo.getP(), dictFo.getPs()),
            new QueryWrapperPlus<Dict>().selectPage(dictFo).orderByDesc("project", "dtype", "create_date"));
        return R.ok(SimpleDictVo.convert(data));
    }

    /**
     * 条件查询
     * 分页查询二级字典信息
     * @return 分页对象
     */
    @GetMapping("/getPage2")
    public R<IPage<Tree<Integer>> > getMutilPage(@Valid DictFo dictFo) {
        // 不指定默认是未删除的
        if (dictFo.getDelFlag() == null) {
            dictFo.setDelFlag(false);
        }

        List<Dict> data;
        Page<Tree<Integer>> page = null;
        if (dictFo.getId() == null && dictFo.getDtype() == null && !dictFo.getDelFlag()) {
            Page<Dict> p = dictService.page(new Page<>(dictFo.getP(), dictFo.getPs()),
                    new QueryWrapperPlus<Dict>().ne("p_id", 0)
                            .orderByDesc("project", "dtype").orderByAsc("p_id"));

            page = new Page<>(p.getCurrent(), p.getSize(), p.getTotal());
            data = p.getRecords();
        } else {
            // 只能查一个
            data =  dictService.list(new QueryWrapperPlus<Dict>().selectPage(dictFo).ne("p_id", 0));
            if (data != null && data.size() == 1) {
                data.addAll(dictService.list(new QueryWrapper<Dict>().like("pids", data.get(0).getId() + ",")));
            } else {
                log.error("查询字典信息有误！");
            }
        }
        if (data == null) {
            data = new ArrayList<>();
        }

        List<TreeNode<Integer>> collect = data.stream()
                .map(dict -> {
                    TreeNode<Integer> node = new TreeNode<Integer>(dict.getId(), dict.getPId(), dict.getPId()+"", dict.getSort());
                    node.setExtra(new HashMap<String, Object>(6){{
                        put("pId", dict.getPId());
                        put("project", dict.getProject());
                        put("dtype", dict.getDtype());
                        put("dkey", dict.getDkey());
                        put("description", dict.getDescription());
                        put("sort", dict.getSort());
                        put("createDate", dict.getCreateDate());
                        put("createBy", dict.getCreateBy());
                        put("updateDate", dict.getUpdateDate());
                        put("updateBy", dict.getUpdateBy());
                        put("delFlag", dict.getDelFlag());
                        put("pids", dict.getPids());
                    }});
                    return node;
                }).collect(Collectors.toList());
        List<Tree<Integer>> info =  TreeUtil.build(collect, data.stream().map(Dict::getPId).min(Integer::compareTo).get());

        if (page == null) {
            page = new Page<>(dictFo.getP(), dictFo.getPs(), data.size());
        }
        page.setRecords(info);
        return R.ok(page);
    }

    /**
     * 修改字典信息
     * @param dict
     * @return
     */
    @PutMapping
    public R updateDict(@Valid @RequestBody Dict dict) {
        return dictService.updateById(dict) ? R.ok() : R.failed();
    }

    /**
     * 添加一条字典记录
     * @param dict
     * @return
     */
    @PostMapping("/add")
    public R add(@Valid @RequestBody Dict dict) {
        dict.setId(null);
        // 处理逻辑删除的 可以将逻辑删除的恢复了

        Dict one = dictService.getOne(new QueryWrapper<Dict>().eq("dtype", dict.getDtype()).eq("dkey", dict.getDkey()));
        if (one != null && one.getDelFlag()) {
            one.setDelFlag(false);
            return dictService.updateById(one) ? R.ok(null, "数据恢复成功！") : R.failed("数据保存失败！");
        }
        // 若是二级菜单的处理
        if (dict.getPId() != null && dict.getPId() > 0) {
            Dict tmp = dictService.getById(dict.getPId());
            if (tmp != null) {
                dict.setPids(tmp.getPids() + "," + dict.getPId());
            }
        }

        return dictService.save(dict) ? R.ok(null, "数据保存成功！") : R.failed("数据保存失败！");
    }

    /**
     * 该接口允许强制删除
     * @param id
     * @param force
     * @return
     */
    @DeleteMapping("/{id}")
    public R removeById(@PathVariable @Min(0) Integer id, @RequestParam(required = false) Boolean force) {
        boolean flag;
        if (force) {
            flag = dictService.removeById(id);
        } else {
            flag = dictService.update(new UpdateWrapper<Dict>().set("del_flag", 1).eq("id", id));
        }
        return flag ? R.ok(null, "删除成功！") : R.failed("删除失败！");
    }
}
